#include "EditorManager.hpp"
#include "General Structures.hpp"

EditorManager::EditorManager()
{
	// GUI etc
	m_pClipPlane = new ClippingPlane();
	m_pSelectionBoxHandler = new SelectionBoxHandler();
	m_pCamera = new Camera(m_pClipPlane);
	m_DrawSelectionBox = true;

	// Rooms
	m_pRoomGrid = new RoomGrid(this);
	m_pRoomManager = new RoomManager();
	m_pRoomCreator = new RoomCreator();
	
	m_CreateRoom = false;
	m_CreatePath = false;
	

	// Events
	m_pEditorEvents = new EditorEventHandler();
	m_pEditorEvents->SetEditorManager(this);

	// Data
	m_pMapData = new MapData();

	// GUI
	m_pEditorGUI = new EditorGUI(this);
	GUI->RegisterPanel(Key->GetPanelIDs()->Editor_Buttons);
	GUI->ActivatePanel();

	// Minimap
	m_pMinimap = new Minimap(m_pClipPlane);

		
	m_Density = .5;
	m_PathWidth = 1;
	m_SmoothPath = -.1;
	m_PathRiver = false;
	m_EnableRoomMovement = false;
	m_MergePathListsInRoomManager = true;


	// Setup our map
	MapData mapData;
	mapData.MapScript = "lol";
	mapData.MapName = "test";
	mapData.h = 100;
	mapData.w = 100;

	DataLoader->LoadData(mapData);

	MapGen->RegisterMap(MapGen->CreateMap(ImageManager->GetImageID("water"), 100, 100));
	Room test = MapGen->GetLastRoom();
	BaseRoom base;
	base.x1.max = test.x1;	base.x1.min = test.x1;
	base.x2.max = test.x2;	base.x2.min = test.x2;
	base.y1.max = test.y1;	base.y1.min = test.y1;
	base.y2.max = test.y2;	base.y2.min = test.y2;
	base.density = .5;
	base.imgID = test.gfxID;

	m_pRoomManager->AddRoom(base);
	m_pRoomManager->AddRoom(test);
	m_pRoomGrid->BuildBackground(test);

	m_pMinimap->Load(m_pRoomGrid->GetGrid());
	m_pMinimap->RecomputeTexturePosition();

	m_pRoomA = NULL;
	m_pRoomB = NULL;
	m_pMouseOverRoom = NULL;

	m_RoomSelectionStart = 1;

}

EditorManager::~EditorManager()
{
	// GUI etc
	NullDelete(m_pEditorGUI);
	NullDelete(m_pClipPlane);
	NullDelete(m_pSelectionBoxHandler);

	// Rooms
	NullDelete(m_pRoomGrid);
	NullDelete(m_pRoomManager);
	NullDelete(m_pRoomCreator);

	// Minimap
	NullDelete(m_pMinimap);
	
	// Events
	NullDelete(m_pEditorEvents);

	// Data
	NullDelete(m_pMapData);

}

// Render the editor
void EditorManager::Render(const SDL_Event& event)
{
	m_pRoomGrid->Render(true);
	//m_pRoomGrid->Render();

	// render our selected rooms
	if(m_pMouseOverRoom != NULL && !m_DrawSelectionBox)
		DrawPrimitives->DrawRectangle(m_pMouseOverRoom->x1 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pMouseOverRoom->y1 * TILE_DIMENSIONS - m_pClipPlane->GetY(),
				m_pMouseOverRoom->x2 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pMouseOverRoom->y2 * TILE_DIMENSIONS - m_pClipPlane->GetY(), Key->GetColor("200, 200, 200, 200"), .5);

	if(m_pRoomA != NULL && !m_DrawSelectionBox)
		DrawPrimitives->DrawRectangle(m_pRoomA->x1 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pRoomA->y1 * TILE_DIMENSIONS - m_pClipPlane->GetY(),
				m_pRoomA->x2 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pRoomA->y2 * TILE_DIMENSIONS - m_pClipPlane->GetY(), Key->GetColor("150, 150, 150, 200"), .5);

	if(m_pRoomB != NULL && !m_DrawSelectionBox)
		DrawPrimitives->DrawRectangle(m_pRoomB->x1 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pRoomB->y1 * TILE_DIMENSIONS - m_pClipPlane->GetY(),
				m_pRoomB->x2 * TILE_DIMENSIONS - m_pClipPlane->GetX(), m_pRoomB->y2 * TILE_DIMENSIONS - m_pClipPlane->GetY(), Key->GetColor("100, 100, 100, 200"), .5);

	if(m_DrawSelectionBox) // only render the selection box if told to
		m_pSelectionBoxHandler->Render(m_pClipPlane);

	// Render GUI last
	m_pEditorGUI->Render();
	//m_pMinimap->RenderMinimap(m_pRoomManager->GetRooms());
	m_pMinimap->RenderMinimap();
	m_pMinimap->RenderScreen();
	//Log->Display();
}

// Handle Events
void EditorManager::HandleEvents(SDL_Event *event)
{
	m_pEditorEvents->HandleEvents(event);
	m_pEditorGUI->HandleEvents(event);
}

void EditorManager::Update()
{
	// Update the GUI
	m_pEditorGUI->Update();
	m_pEditorEvents->Update();

	// Scrolling has to be updated every frame	

	if(m_CreateRoom)
	{
		m_CreateRoom = false;

		GameRectangle aRect(m_pSelectionBoxHandler->GetLocation("max x1y1").x, 
							m_pSelectionBoxHandler->GetLocation("max x1y1").y,
							m_pSelectionBoxHandler->GetLocation("max x2y2").x - m_pSelectionBoxHandler->GetLocation("max x1y1").x,
							m_pSelectionBoxHandler->GetLocation("max x2y2").y - m_pSelectionBoxHandler->GetLocation("max x1y1").y);

		aRect = ScaledRect(aRect, .5);

		BaseRoom baseRoom;
		baseRoom.x1.max = (double)(m_pSelectionBoxHandler->GetLocation("max x1y1").x ) / (double)TILE_DIMENSIONS;
		//baseRoom.x1.min = (double)(m_pSelectionBoxHandler->GetLocation("max x1y1").x * 1.1) / (double)TILE_DIMENSIONS;
		baseRoom.x1.min = (double)(aRect.x1) / (double)TILE_DIMENSIONS;
		
		baseRoom.x2.max = (double)(m_pSelectionBoxHandler->GetLocation("max x2y2").x ) / (double)TILE_DIMENSIONS;
		//baseRoom.x2.min = (double)(m_pSelectionBoxHandler->GetLocation("max x2y2").x * .95) / (double)TILE_DIMENSIONS;
		baseRoom.x2.min = (double)(aRect.x2) / (double)TILE_DIMENSIONS;

		baseRoom.y1.max = (double)(m_pSelectionBoxHandler->GetLocation("max x1y1").y ) / (double)TILE_DIMENSIONS;
		//baseRoom.y1.min = (double)(m_pSelectionBoxHandler->GetLocation("max x1y1").y * 1.1) / (double)TILE_DIMENSIONS;
		baseRoom.y1.min = (double)(aRect.y1 ) / (double)TILE_DIMENSIONS;

		baseRoom.y2.max = (double)(m_pSelectionBoxHandler->GetLocation("max x2y2").y ) / (double)TILE_DIMENSIONS;
		//baseRoom.y2.min = (double)(m_pSelectionBoxHandler->GetLocation("max x2y2").y * .95) / (double)TILE_DIMENSIONS;
		baseRoom.y2.min = (double)(aRect.y2) / (double)TILE_DIMENSIONS;

		baseRoom.imgID = m_ActiveImgID;
		baseRoom.algorithm = m_ActiveAlgorithm;
		baseRoom.density = m_Density;
		baseRoom.name = "test";
		
		Room generated = m_pRoomCreator->GenerateRoom(baseRoom);

		baseRoom.ID = generated.ID;
		m_pRoomManager->AddRoom(baseRoom);
		MapGen->PostProcessRoomCorrectWay(generated); // post process our room :P
		m_pRoomManager->AddRoom(generated);
		m_pRoomGrid->AddRoom(generated);

		m_pMinimap->Load(generated);
	}

	if(m_CreatePath)
	{
		m_CreatePath = false;

		if(m_pRoomA != NULL && m_pRoomB != NULL)
		{
			// add the path to the room manager and the grid
			BasePath basePath;
			basePath.imgID = m_ActiveImgID;
			basePath.ID_a = m_pRoomA->ID;
			basePath.ID_b = m_pRoomB->ID;
			basePath.width = m_PathWidth;
			
			basePath.smoothingPercentage = m_SmoothPath;
			basePath.river = m_PathRiver;

			MapGen->AddPath(m_pRoomA->ID, m_pRoomB->ID, m_PathWidth, m_ActiveImgID, m_SmoothPath, m_PathRiver);
			Room generated = MapGen->GetLastRoom();
			MapGen->PostProcessRoomCorrectWay(generated);
			
			m_pRoomManager->AddRoom(generated);

			
			basePath.roomID = MapGen->GetLastRoom().ID;
			m_pRoomManager->AddPath(basePath, m_MergePathListsInRoomManager);

			m_pRoomGrid->AddRoom(generated);

			m_pMinimap->Load(generated);
		}

	}



	if(m_RemoveRoom)
	{
		m_RemoveRoom = false;
		if(m_pRoomA != NULL)
		{
			m_pMinimap->Remove(*m_pRoomA);
			m_pRoomManager->RemoveRoom(*m_pRoomA);
			//MapGen->RemoveRoom(m_pRoomA);
			m_pRoomA = NULL;
		}
	}
}